home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 001-025 / disk_016 / source.files / seeilbm.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  20KB  |  618 lines

  1.  /*****************************************************************
  2.  *
  3.  * Read an ILBM file and display as a screen/window until closed.
  4.  *   Simulated close gadget in upper left corner of window.
  5.  *   Clicking below title bar area toggles screen bar for dragging.
  6.  *
  7.  *  By Carolyn Scheppner   CBM  03/15/86
  8.  *
  9.  * Based on early ShowILBM.c    11/12/85
  10.  *  By Jerry Morrison, Steve Shaw, and Steve Hayes, Electronic Arts.
  11.  *  This software is in the public domain.
  12.  *
  13.  * >>NOTE<<: This example must be linked with additional IFF rtn files.
  14.  *           See linkage information below.
  15.  *
  16.  * The IFF reader portion is essentially a recursive-descent parser.
  17.  * This program will look into a CAT or LIST to find a FORM ILBM, but it
  18.  * won't look inside another FORM type for a nested FORM ILBM.
  19.  *
  20.  * The display portion is specific to the Commodore Amiga computer.
  21.  *
  22.  * Linkage Information:
  23.  *
  24.  * FROM     LStartup.obj, SeeILBM.o, iffr.o, ilbmr.o, unpacker.o
  25.  * TO       SeeILBM
  26.  * LIBRARY  LC.lib, Amiga.lib
  27.  * 
  28.  **************************************************************************/
  29.  
  30. #include <exec/types.h>
  31. #include <exec/memory.h>
  32. #include <libraries/dos.h>
  33. #include <graphics/gfxbase.h>
  34. #include <graphics/rastport.h>
  35. #include <graphics/gfx.h>
  36. #include <graphics/view.h>
  37. #include <workbench/startup.h>
  38. #include <intuition/intuition.h>
  39. #include <lattice/stdio.h>
  40.  
  41. #include "iff/ilbm.h"
  42.  
  43. /* This example's max number of planes in a bitmap. Could use MaxAmDepth. */
  44. #define EXDepth 5
  45. #define maxColorReg (1<<EXDepth)
  46. #define MIN(a,b) ((a)<(b)?(a):(b))
  47.  
  48. #define SafeFreeMem(p,q) {if(p)FreeMem(p,q);}
  49.     
  50. /* Define the size of a temp buffer used in unscrambling the ILBM rows.*/
  51. #define bufSz 512
  52.  
  53. /* general usage pointers */
  54. struct GfxBase       *GfxBase;
  55. struct IntuitionBase *IntuitionBase;
  56. struct IntuiMessage  *message;
  57.  
  58. /* Globals for displaying an image */
  59. struct Screen   *screen1;
  60. struct Window   *window1;
  61. struct RastPort *rport1;
  62. struct ViewPort *vport1;
  63.  
  64. struct BitMap   tBitMap;      /* Temp BitMap struct for small pics  */
  65.  
  66. /* For WorkBench startup */    
  67. extern struct WBStartup *WBenchMsg;
  68. BOOL   fromWB;
  69. struct FileLock *startLock, *newLock;
  70.  
  71. /* Other globals */
  72. int   i, error;
  73. BYTE  c;
  74. BOOL  TBtoggle, Done;
  75. ULONG class, code, pBytes;
  76.  
  77. /* Structures for new Screen, new Window */
  78.  
  79. struct   TextAttr       TextFont = {
  80.    "topaz.font",                    /* Font Name   */
  81.    TOPAZ_EIGHTY,                    /* Font Height */
  82.    FS_NORMAL,                       /* Style       */
  83.    FPF_ROMFONT,                     /* Preferences */
  84.    };
  85.  
  86. struct   NewScreen      ns = {
  87.    0, 0,                                  /* LeftEdge and TopEdge   */
  88.    0, 0,                                  /* Width and Height       */
  89.    0,                                     /* Depth                  */
  90.    -1, -1,                                /* DetailPen and BlockPen */
  91.    NULL,                                  /* Special display modes  */
  92.    CUSTOMSCREEN,                          /* Screen Type            */
  93.    &TextFont,                             /* Use my font            */
  94.    NULL,                                  /* Title                  */
  95.    NULL,                                  /* No gadgets yet         */
  96.    NULL,                                  /* Ptr to CustomBitmap    */
  97.    };
  98.  
  99. struct   NewWindow      nw = {
  100.    0, 0,                                  /* LeftEdge and TopEdge */
  101.    0, 0,                                  /* Width and Height */
  102.    -1, -1,                                /* DetailPen and BlockPen */
  103.    MOUSEBUTTONS,                          /* IDCMP Flags */
  104.    ACTIVATE
  105.    |BACKDROP
  106.    |BORDERLESS,                           /* Flags */
  107.    NULL, NULL,                            /* Gadget and Image pointers */
  108.    NULL,                                  /* Title string */
  109.    NULL,                                  /* Put Screen ptr here */
  110.    NULL,                                  /* SuperBitMap pointer */
  111.    0, 0,                                  /* MinWidth and MinHeight */
  112.    0, 0,                                  /* MaxWidth and MaxHeight */
  113.    CUSTOMSCREEN,                          /* Type of window */
  114.    };
  115.  
  116. USHORT  allBgColor[32];
  117.  
  118.  
  119. /* Message strings for IFFP codes. */
  120. char MsgOkay[]        = {"(IFF_OKAY) No FORM ILBM in the file." };
  121. char MsgEndMark[]     = {"(END_MARK) How did you get this message?" };
  122. char MsgDone[]        = {"(IFF_DONE) All done."};
  123. char MsgDos[]         = {"(DOS_ERROR) The DOS returned an error." };
  124. char MsgNot[]         = {"(NOT_IFF) Not an IFF file." };
  125. char MsgNoFile[]      = {"(NO_FILE) No such file found." };
  126. char MsgClientError[] = {"(CLIENT_ERROR) ShowILBM bug or insufficient RAM."};
  127. char MsgForm[]        = {"(BAD_FORM) A malformed FORM ILBM." };
  128. char MsgShort[]       = {"(SHORT_CHUNK) A malformed FORM ILBM." };
  129. char MsgBad[]         = {"(BAD_IFF) A mangled IFF file." };
  130.  
  131. /* THESE MUST APPEAR IN RIGHT ORDER!! */
  132. char *IFFPMessages[-LAST_ERROR+1] = {
  133.     /*IFF_OKAY*/  MsgOkay,
  134.     /*END_MARK*/  MsgEndMark,
  135.     /*IFF_DONE*/  MsgDone,
  136.     /*DOS_ERROR*/ MsgDos,
  137.     /*NOT_IFF*/   MsgNot,
  138.     /*NO_FILE*/   MsgNoFile,
  139.     /*CLIENT_ERROR*/ MsgClientError,
  140.     /*BAD_FORM*/  MsgForm,
  141.     /*SHORT_CHUNK*/  MsgShort,
  142.     /*BAD_IFF*/   MsgBad
  143.     };
  144.  
  145. /*------------ ILBM reader -----------------------------------------------*/
  146. /* ILBMFrame is our "client frame" for reading FORMs ILBM in an IFF file.
  147.  * We allocate one of these on the stack for every LIST or FORM encountered
  148.  * in the file and use it to hold BMHD & CMAP properties. We also allocate
  149.  * an initial one for the whole file.
  150.  * We allocate a new GroupContext (and initialize it by OpenRIFF or
  151.  * OpenRGroup) for every group (FORM, CAT, LIST, or PROP) encountered. It's
  152.  * just a context for reading (nested) chunks.
  153.  *
  154.  * If we were to scan the entire example file outlined below:
  155.  *    reading          proc(s)                new               new
  156.  *
  157.  * --whole file--   ReadPicture+ReadIFF   GroupContext        ILBMFrame
  158.  * CAT              ReadICat                GroupContext
  159.  *   LIST           GetLiILBM+ReadIList       GroupContext        ILBMFrame
  160.  *     PROP ILBM    GetPrILBM                   GroupContext
  161.  *       CMAP       GetCMAP
  162.  *       BMHD       GetBMHD
  163.  *     FORM ILBM    GetFoILBM                   GroupContext        ILBMFrame
  164.  *       BODY       GetBODY
  165.  *     FORM ILBM    GetFoILBM                   GroupContext        ILBMFrame
  166.  *       BODY       GetBODY
  167.  *   FORM ILBM      GetFoILBM                 GroupContext        ILBMFrame
  168.  */
  169. typedef struct {
  170.    ClientFrame clientFrame;
  171.    UBYTE foundBMHD;
  172.    UBYTE nColorRegs;
  173.    BitMapHeader bmHdr;
  174.    Color4 colorMap[maxColorReg];
  175.    /* If you want to read any other property chunks, e.g. GRAB or CAMG, add
  176.     * fields to this record to store them. */
  177.    } ILBMFrame;
  178.  
  179.  
  180. /* NOTE: For a simple version of this program, set Fancy to 0.
  181.  * That'll compile a program that skips all LISTs and PROPs in the input
  182.  * file. It will look in CATs for FORMs ILBM. That's suitable for most uses.
  183.  *
  184.  * For a fancy version that handles LISTs and PROPs, set Fancy to 1. */
  185.  
  186. #define Fancy  1
  187.  
  188. /* Modified by C. Scheppner */
  189. /*  iFrame    made global -  moved from ReadPicture() */
  190. /*  ilbmFrame made global -  moved from GetFoILBM()   */
  191.  
  192. ILBMFrame   iFrame;       /* top level client frame */
  193. ILBMFrame   ilbmFrame;    /* global bitmap frame    */
  194.  
  195.  
  196. /** main() ****************************************************************/
  197. main(argc, argv)
  198.    int argc;
  199.    char **argv;
  200.    {
  201.    LONG            file;
  202.    IFFP            iffp = NO_FILE;
  203.    struct WBArg    *arg;  
  204.    char            *filename;
  205.  
  206.    fromWB = (argc==0) ? TRUE : FALSE;
  207.  
  208.    if(argc>1)                 /* Passed filename via command line  */
  209.       {
  210.       filename = argv[1];
  211.       }
  212.    else if ((argc==0)&&(WBenchMsg->sm_NumArgs > 1))
  213.       {                        /* Passed filename via  WorkBench */
  214.       arg = WBenchMsg->sm_ArgList;
  215.       arg++;
  216.       filename = (char *)arg->wa_Name;
  217.       newLock    = (struct FileLock *)arg->wa_Lock;
  218.       startLock  = (struct FileLock *)CurrentDir(newLock);
  219.       }
  220.    else if (argc==1)           /* From CLI but no filename */
  221.       cleanexit("Usage: 'SeeILBM filename'\n");
  222.    else                        /* From WB but no filename */
  223.       cleanexit("\nClick ONCE on SeeILBM\nSHIFT and DoubleClick on Pic\n");
  224.  
  225.  
  226.  
  227.    if(!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0)))
  228.       cleanexit("Can't open graphics library\n");
  229.  
  230.    if(!(IntuitionBase=
  231.           (struct IntuitionBase *)OpenLibrary("intuition.library",0)))
  232.       cleanexit("Can't open graphics library\n");
  233.  
  234.    if(file = Open(filename, MODE_OLDFILE))
  235.       {
  236.       printf("\nCLICK PIC TOP LEFT TO END DISPLAY\n");
  237.       printf("CLICK LOWER TO TOGGLE DRAG BAR\n");
  238.       Delay(150);  /* wait about 3 seconds to give person time to read it */
  239.  
  240.       iffp = ReadPicture(file);
  241.       Close(file);
  242.       if (iffp == IFF_DONE)
  243.          {
  244.          error = DisplayPic(&ilbmFrame);
  245.          if(error)  cleanexit("Can't open screen or window\n");
  246.  
  247.          TBtoggle   = FALSE;      /* Title bar toggle */
  248.          Done       = FALSE;      /* Close flag       */
  249.          while (!Done)
  250.             {
  251.             if(1<<window1->UserPort->mp_SigBit)   chkmsg();
  252.             }
  253.          }
  254.       else cleanexit(IFFPMessages[-iffp]);
  255.       }
  256.    else cleanexit("Picture file not found.\n");
  257.  
  258.    cleanup();
  259.    }
  260.  
  261.  
  262. chkmsg()
  263.    {
  264.    while(message=(struct IntuiMessage *)GetMsg(window1->UserPort))
  265.       {
  266.       class = message->Class;
  267.       code  = message->Code;
  268.       ReplyMsg(message);
  269.       switch(class)
  270.          {
  271.          case MOUSEBUTTONS:
  272.             if ((code == SELECTDOWN)&&
  273.                   (window1->MouseX < 10)&&(window1->MouseY<10))
  274.                {
  275.                Done = TRUE;
  276.                }
  277.             else if ((code == SELECTDOWN)&&
  278.                        (window1->MouseY>10)&&(TBtoggle==FALSE))
  279.                {
  280.                TBtoggle = TRUE;
  281.                ShowTitle(screen1,TRUE);
  282.                }
  283.             else if ((code == SELECTDOWN)&&
  284.                        (window1->MouseY>10)&&(TBtoggle==TRUE))
  285.                {
  286.                TBtoggle = FALSE;
  287.                ShowTitle(screen1,FALSE);
  288.                }
  289.             break;
  290.          default:
  291.             printf("Unknown IDCMP message\n");
  292.          }
  293.       }
  294.    }
  295.  
  296.  
  297. cleanexit(errstr)
  298.    char  *errstr;
  299.    {
  300.    printf("\n %s \n",errstr);
  301.    cleanup();
  302.    if (fromWB)    /* Wait so user can read messages */
  303.       {
  304.       printf("\nPRESS RETURN TO CLOSE THIS WINDOW\n");
  305.       while ((c=getchar()) != '\n');
  306.       }
  307.    exit();
  308.    }
  309.  
  310. cleanup()
  311.    {
  312.    /* tBitMap planes were deallocated in DisplayPic() */
  313.    if (window1) CloseWindow(window1);
  314.    if (screen1) CloseScreen(screen1);
  315.    if (IntuitionBase) CloseLibrary(IntuitionBase);
  316.    if (GfxBase)       CloseLibrary(GfxBase);
  317.    if (newLock != startLock)  CurrentDir(startLock);
  318.    }
  319.  
  320.  
  321. /** getBitMap() *********************************************************
  322.  *
  323.  * Open screen or temp bitmap.
  324.  *   Returns ptr destBitMap  or  0 = error
  325.  *
  326.  *************************************************************************/
  327. struct BitMap *getBitMap(ptilbmFrame)
  328.    ILBMFrame *ptilbmFrame;
  329.    {
  330.    int     i, nPlanes, plsize;
  331.    SHORT  sWidth, sHeight, dWidth, dHeight;
  332.    struct BitMap *destBitMap;
  333.  
  334.    sWidth  = ptilbmFrame->bmHdr.w;
  335.    sHeight = ptilbmFrame->bmHdr.h;
  336.    dWidth  = ptilbmFrame->bmHdr.pageWidth;
  337.    dHeight = ptilbmFrame->bmHdr.pageHeight;
  338.    nPlanes   = MIN(ptilbmFrame->bmHdr.nPlanes, EXDepth);
  339.  
  340.    for (i = 0; i < ptilbmFrame->nColorRegs; i++)
  341.       {
  342.       allBgColor[i] = ptilbmFrame->colorMap[0];
  343.       }
  344.  
  345.    ns.Width  = dWidth;
  346.    ns.Height = dHeight;
  347.    ns.Depth  = nPlanes;
  348.  
  349.    if (ptilbmFrame->bmHdr.pageWidth <= 320)
  350.       ns.ViewModes = 0;
  351.    else
  352.       ns.ViewModes = HIRES;
  353.  
  354.    if (ptilbmFrame->bmHdr.pageHeight > 200)
  355.       ns.ViewModes |= LACE;
  356.  
  357.    if ((screen1 = (struct Screen *)OpenScreen(&ns))==NULL)    return(0);
  358.  
  359.    vport1 = &screen1->ViewPort;
  360.    LoadRGB4(vport1, &allBgColor[0], ptilbmFrame->nColorRegs);
  361.  
  362.    nw.Width  = dWidth;
  363.    nw.Height = dHeight;
  364.    nw.Screen = screen1;
  365.  
  366.    if ((window1 = (struct Window *)OpenWindow(&nw))==NULL)    return(0);
  367.  
  368.    ShowTitle(screen1, FALSE);
  369.  
  370.    if ((sWidth == dWidth) && (sHeight == dHeight))
  371.       {
  372.       destBitMap = (struct BitMap *)screen1->RastPort.BitMap;
  373.       }
  374.    else
  375.       {
  376.       InitBitMap( &tBitMap,
  377.                   nPlanes,
  378.                   sWidth,
  379.                   sHeight);
  380.  
  381.       plsize = RowBytes(ptilbmFrame->bmHdr.w) * ptilbmFrame->bmHdr.h;
  382.       if (tBitMap.Planes[0] =
  383.        (PLANEPTR)AllocMem(nPlanes * plsize, MEMF_CHIP))
  384.          {
  385.          for (i = 1; i < nPlanes; i++)
  386.             tBitMap.Planes[i] = (PLANEPTR)tBitMap.Planes[0] + plsize*i;
  387.          destBitMap = &tBitMap;
  388.          }
  389.       else
  390.          {
  391.          return(0);  /* can't allocate temp BitMap */
  392.          }
  393.       }
  394.    return(destBitMap);          /* destBitMap allocated */
  395.    }
  396.  
  397.  
  398. /** DisplayPic() *********************************************************
  399.  *
  400.  * Display loaded bitmap.  If tBitMap, first transfer to screen.
  401.  *
  402.  *************************************************************************/
  403. DisplayPic(ptilbmFrame)
  404.    ILBMFrame *ptilbmFrame;
  405.    {
  406.    int    i, row, byte, nrows, nbytes;
  407.    struct BitMap  *tbp, *sbp; /* temp and screen BitMap ptrs */
  408.    UBYTE  *tpp, *spp;         /* temp and screen plane ptrs  */
  409.  
  410.    if (tBitMap.Planes[0])     /* transfer from tBitMap if nec. */
  411.       {
  412.       tbp = &tBitMap;
  413.       sbp = screen1->RastPort.BitMap;
  414.       nrows  = MIN(tbp->Rows, sbp->Rows);
  415.       nbytes = MIN(tbp->BytesPerRow, sbp->BytesPerRow);
  416.  
  417.       for (i = 0; i < sbp->Depth; i++)
  418.          {
  419.          tpp = (UBYTE *)tbp->Planes[i];
  420.          spp = (UBYTE *)sbp->Planes[i];
  421.          for (row = 0; row < nrows; row++)
  422.             {
  423.             tpp = tbp->Planes[i] + (row * tbp->BytesPerRow);
  424.             spp = sbp->Planes[i] + (row * sbp->BytesPerRow);
  425.             for (byte = 0; byte < nbytes; byte++)
  426.                {
  427.                *spp++ = *tpp++;
  428.                }
  429.             }
  430.          }
  431.       /*  Can now deallocate the temp BitMap  */
  432.       FreeMem(tBitMap.Planes[0],
  433.                  tBitMap.BytesPerRow * tBitMap.Rows * tBitMap.Depth);
  434.       }
  435.  
  436.    vport1 = &screen1->ViewPort;
  437.    LoadRGB4(vport1, ptilbmFrame->colorMap, ptilbmFrame->nColorRegs);
  438.  
  439.    return(0);
  440.    }
  441.  
  442.  
  443. /** GetLiILBM() **********************************************************
  444.  *
  445.  * Called via ReadPicture to handle every LIST encountered in an IFF file.
  446.  *
  447.  *************************************************************************/
  448. #if Fancy
  449. IFFP GetLiILBM(parent)
  450. GroupContext *parent; {
  451.     ILBMFrame newFrame;   /* allocate a new Frame */
  452.  
  453.     newFrame = *(ILBMFrame *)parent->clientFrame;  /* copy parent frame */
  454.  
  455.     return( ReadIList(parent, (ClientFrame *)&newFrame) );
  456.     }
  457. #endif
  458.  
  459.  
  460. /** GetPrILBM() **********************************************************
  461.  *
  462.  * Called via ReadPicture to handle every PROP encountered in an IFF file.
  463.  * Reads PROPs ILBM and skips all others.
  464.  *
  465.  *************************************************************************/
  466. #if Fancy
  467. IFFP GetPrILBM(parent)
  468. GroupContext *parent; {
  469.    /*compilerBug register*/ IFFP iffp;
  470.    GroupContext propContext;
  471.    ILBMFrame *ilbmFrame = (ILBMFrame *)parent->clientFrame;
  472.  
  473.    if (parent->subtype != ID_ILBM)
  474.       return(IFF_OKAY);   /* just continue scaning the file */
  475.  
  476.    iffp = OpenRGroup(parent, &propContext);
  477.    CheckIFFP();
  478.  
  479.    do switch (iffp = GetPChunkHdr(&propContext)) {
  480.       case ID_BMHD: {
  481.          ilbmFrame->foundBMHD = TRUE;
  482.          iffp = GetBMHD(&propContext, &ilbmFrame->bmHdr);
  483.          break; }
  484.       case ID_CMAP: {
  485.          ilbmFrame->nColorRegs = maxColorReg; /* room for this many */
  486.          iffp = GetCMAP( &propContext, (WORD *)ilbmFrame->colorMap,
  487.                           &ilbmFrame->nColorRegs);
  488.          break; }
  489.  
  490.       } while (iffp >= IFF_OKAY);/* loop if valid ID of ignored chunk or
  491.                                   * subrtn returned IFF_OKAY (no errors).*/
  492.  
  493.    CloseRGroup(&propContext);
  494.    return(iffp == END_MARK ? IFF_OKAY : iffp);
  495.    }
  496. #endif
  497.  
  498.  
  499. /** GetFoILBM() **********************************************************
  500.  *
  501.  * Called via ReadPicture to handle every FORM encountered in an IFF file.
  502.  * Reads FORMs ILBM and skips all others.
  503.  * Inside a FORM ILBM, it stops once it reads a BODY. It complains if it
  504.  * finds no BODY or if it has no BMHD to decode the BODY.
  505.  *
  506.  * Once we find a BODY chunk, we'll allocate the BitMap and read the image.
  507.  *
  508.  * Modified by C. Scheppner:  ilbmFrame moved above main making it
  509.  *                            global so main can call DisplayPic()
  510.  *
  511.  *************************************************************************/
  512. IFFP GetFoILBM(parent)
  513.    GroupContext *parent;
  514.    {
  515.    IFFP iffp;
  516.    GroupContext formContext;
  517.    BYTE buffer[bufSz];
  518.    struct BitMap *destBitMap;
  519.  
  520.    if (parent->subtype != ID_ILBM)
  521.       return(IFF_OKAY);   /* just continue scaning the file */
  522.  
  523.    ilbmFrame = *(ILBMFrame *)parent->clientFrame;
  524.    iffp = OpenRGroup(parent, &formContext);
  525.    CheckIFFP();
  526.  
  527.    do switch (iffp = GetFChunkHdr(&formContext)) {
  528.       case ID_BMHD: {
  529.          ilbmFrame.foundBMHD = TRUE;
  530.          iffp = GetBMHD(&formContext, &ilbmFrame.bmHdr);
  531.          break; }
  532.       case ID_CMAP: {
  533.          ilbmFrame.nColorRegs = maxColorReg;  /* we have room for this many */
  534.          iffp = GetCMAP(&formContext, (WORD *)ilbmFrame.colorMap,
  535.                            &ilbmFrame.nColorRegs);
  536.          break; }
  537.       case ID_BODY: {
  538.          if (!ilbmFrame.foundBMHD)  return(BAD_FORM);   /* No BMHD chunk! */
  539.  
  540.          if(destBitMap=(struct BitMap *)getBitMap(&ilbmFrame))
  541.             {
  542.             iffp = GetBODY( &formContext,
  543.                             destBitMap,
  544.                             NULL,
  545.                             &ilbmFrame.bmHdr,
  546.                             buffer,
  547.                             bufSz);
  548.             if (iffp == IFF_OKAY) iffp = IFF_DONE;   /* Eureka */
  549.             }
  550.          else
  551.             iffp = CLIENT_ERROR;   /* not enough RAM for the bitmap */
  552.          break; }
  553.  
  554.       case END_MARK: {
  555.          iffp = BAD_FORM;
  556.          break; }
  557.  
  558.    } while (iffp >= IFF_OKAY);  /* loop if valid ID of ignored chunk or a
  559.            * subroutine returned IFF_OKAY (no errors).*/
  560.  
  561.    if (iffp != IFF_DONE)  return(iffp);
  562.  
  563.    CloseRGroup(&formContext);
  564.    return(iffp);
  565.    }
  566.  
  567. /** Notes on extending GetFoILBM *****************************************
  568.  *
  569.  * To read more kinds of chunks, just add clauses to the switch statement.
  570.  * To read more kinds of property chunks (GRAB, CAMG, etc.) add clauses to
  571.  * the switch statement in GetPrILBM, too.
  572.  *
  573.  * To read a FORM type that contains a variable number of data chunks--e.g.
  574.  * a FORM FTXT with any number of CHRS chunks--replace the ID_BODY case with
  575.  * an ID_CHRS case that doesn't set iffp = IFF_DONE, and make the END_MARK
  576.  * case do whatever cleanup you need.
  577.  *
  578.  *************************************************************************/
  579.  
  580.  
  581. /** ReadPicture() ********************************************************
  582.  *
  583.  * Read a picture from an IFF file, given a file handle open for reading.
  584.  *
  585.  * Modified by Carolyn Scheppner   CBM   03-86
  586.  *   iFrame made global (above main)
  587.  *   Close(file) moved to main
  588.  *
  589.  *************************************************************************/
  590. IFFP ReadPicture(file)
  591.       LONG file;
  592.    {
  593.    IFFP iffp = IFF_OKAY;
  594.  
  595. #if Fancy
  596.    iFrame.clientFrame.getList = GetLiILBM;
  597.    iFrame.clientFrame.getProp = GetPrILBM;
  598. #else
  599.    iFrame.clientFrame.getList = SkipGroup;
  600.    iFrame.clientFrame.getProp = SkipGroup;
  601. #endif
  602.    iFrame.clientFrame.getForm = GetFoILBM;
  603.    iFrame.clientFrame.getCat  = ReadICat ;
  604.  
  605.    /* Initialize the top-level client frame's property settings to the
  606.     * program-wide defaults. This example just records that we haven't read
  607.     * any BMHD property or CMAP color registers yet. For the color map, that
  608.     * means the default is to leave the machine's color registers alone.
  609.     * If you want to read a property like GRAB, init it here to (0, 0). */
  610.    iFrame.foundBMHD  = FALSE;
  611.    iFrame.nColorRegs = 0;
  612.  
  613.    iffp = ReadIFF(file, (ClientFrame *)&iFrame);
  614.    return(iffp);
  615.    }
  616.  
  617.  
  618.